home *** CD-ROM | disk | FTP | other *** search
Wrap
#include "FRApp.h" /* FROpponent FRApp::ms_aOpponents[25] = { FROpponent("staddl", PICKUP, 1.8f, true), FROpponent("mp5", GOLF, 1.7f, true), FROpponent("Red Menace", GOLF, 1.7f, true), FROpponent("Linus T", ACLASS, 1.7f, true), FROpponent("John C", MONSTERHUMMER, 1.7f, true), FROpponent("RoadPsycho", HUMMER, 1.6f, true), FROpponent("PsychoDad", HUMMER, 1.6f, true), FROpponent("Al Bundy", DODGE, 1.6f, true), FROpponent("Tux", ACLASS, 1.6f, false), FROpponent("Homer Jay", DODGE, 1.5f, true), FROpponent("Doomer", FUNERALCAR, 1.5f, true), FROpponent("The Duke", HUMMER, 1.5f, true), FROpponent("Stoned Zivi", AMBULANCE, 1.5f, false), FROpponent("EvilMan", GOLF, 1.4f, true), FROpponent("The Devil Himself", MONSTERHUMMER, 1.4f, true), FROpponent("Eat My Shorts", AMBULANCE, 1.4f, true), FROpponent("Undertaker", FUNERALCAR, 1.4f, true), FROpponent("Pot Express", PICKUP, 1.3f, false), FROpponent("EvilWoman", ACLASS, 1.3f, false), FROpponent("Mr. Jack", COP, 1.3f, true), FROpponent("Mr. Nice Guy", PICKUP, 1.3f, false), FROpponent("William G", DODGE, 0.8f, false), FROpponent("Mary Jane", PICKUP, 1.0f, false), FROpponent("Headshot", COP, 1.1f, true), FROpponent("Brainless", COP, 1.0f, true)}; */ FROpponent FRApp::ms_aOpponents[25] = { FROpponent("staddl", PICKUP, 2.0f, true), FROpponent("mp5", GOLF, 1.9f, true), FROpponent("Red Menace", GOLF, 1.9f, true), FROpponent("El Barto", DODGE, 1.8f, true), FROpponent("Wide Load", MONSTERHUMMER, 1.8f, true), FROpponent("Pot Express", PICKUP, 1.8f, false), FROpponent("Mr. Nice Guy", PICKUP, 1.8f, false), FROpponent("Mr. Shoe", DODGE, 1.8f, true), FROpponent("Der Blubb", ACLASS, 1.7f, false), FROpponent("Homer Jay", DODGE, 1.7f, true), FROpponent("Mr. Jack", COP, 1.7f, true), FROpponent("The Duke", HUMMER, 1.7f, true), FROpponent("Brainless", COP, 1.65f, true), FROpponent("Evil Man", GOLF, 1.6f, true), FROpponent("The Devil Himself", MONSTERHUMMER, 1.6f, true), FROpponent("Eat My Shorts", AMBULANCE, 1.5f, true), FROpponent("Evil Woman", ACLASS, 1.5f, false), FROpponent("Undertaker", FUNERALCAR, 1.5f, true), FROpponent("Road Psycho", HUMMER, 1.4f, true), FROpponent("Doomer", FUNERALCAR, 1.4f, true), FROpponent("Psycho Dad", HUMMER, 1.4f, true), FROpponent("Student Driver", ACLASS, 1.0f, false), FROpponent("Mary Jane", PICKUP, 1.3f, false), FROpponent("Headshot", COP, 1.2f, true), FROpponent("Stoned Medic", AMBULANCE, 1.0f, false)}; FRCareerRace FRApp::ms_aRaces[10] = { FRCareerRace("Ambulance Trophy", "Ambulance cars are VERY slow.", "But with your siren on, everybody", "has to let you through!", NORMALRACE, true, AMBULANCE), FRCareerRace("Dope Trophy", "The drug business is very hard.", "Because of that, the cars that transport", "the dope are not only fast, but also armed!", POWERUPKO, true, PICKUP), FRCareerRace("Funeral Cup", "Digging graves is a hard job.", "But some undertakers have a hobby, that", "creates distraction and new CUSTOMERS!", RACETODEATH, true, FUNERALCAR), FRCareerRace("Police Chase", "Cops don't only beat innocent people with their", "truncheons, they also do high speed chases.", "Show that you can do it better!", KNOCKOUT, true, COP), FRCareerRace("Army Training", "The army has the best toys available.", "They are bigger, better and a lot of fun.", "Let's test them!", POWERUPRACE, true, HUMMER), FRCareerRace("Fun Skeet Trophy", "You don't know Fun Skeet 2?", "Then go get it under www.funskeet.de.vu!", "{Sorry for the shameless advertising ;)}", RACETODEATH, false, ACLASS), FRCareerRace("Roach Cup", "Cockroaches could survive a nuclear", "armageddon. But do they also survive a car", "running over them with 250 km/h?", POWERUPKO, false, ACLASS), FRCareerRace("Caffeine Race", "Caffeine is GOOD!", "Everybody who says something", "else is a bitch.", KNOCKOUT, false, ACLASS), FRCareerRace("2Fast4U Challenge", "Who's the fastest?", "Like in many other games,", "this is the question here, too.", NORMALRACE, false, ACLASS), FRCareerRace("Illegal Weapon Race", "Just tuning your car is boring!", "Arming your car with any weapon", "you can get is much more interesting!", POWERUPRACE, false, ACLASS)}; Char FRApp::ms_aacTrackNames[NUM_TRACKS][12] = {"airfield", "church", "hillhole", "railroad", "windydesert"}; TERTTIImplementation(FRAClass, FRCar); TERTTIImplementation(FRAmbulance, FRCar); TERTTIImplementation(FRCop, FRCar); TERTTIImplementation(FRDodge, FRCar); TERTTIImplementation(FRFuneralCar, FRCar); TERTTIImplementation(FRGolf, FRCar); TERTTIImplementation(FRHummer, FRCar); TERTTIImplementation(FRMonsterHummer, FRCar); TERTTIImplementation(FRPickup, FRCar); FRApp FunRacing; FRApp::~FRApp() { UInt16 usCount; SafeDelete(m_pCareer); SafeDeleteA(m_aTrackNodes); SafeDeleteA(m_aTempTrackNodes); SafeDeleteA(m_aAINodes); SafeDeleteA(m_aTempAINodes); for(usCount = 0; usCount < 4; usCount++) SafeDelete(m_apPowerUpIcons[usCount]); for(usCount = 0; usCount < NUM_TRACKS; usCount++) SafeDelete(m_apTrackImages[usCount]); SafeDelete(m_pTacho); SafeDelete(m_pMenuBackground); } void FRApp::Prepare(Char* pcCommandLine) { m_usScreenWidth = 640; m_usScreenHeight = 480; #if TE_PLATFORM == TE_WIN32 m_usScreenBpp = 32; #else m_usScreenBpp = 0; #endif m_usMirrorWidth = 300; m_usMirrorHeight = 75; m_ulTachoSpeed = 0; m_ulCountdown = 0; m_bShowAbortMenu = false; m_fCamDelta= 0; m_ServerPassword = ""; m_bCareerRace = false; m_usDifficulty = 2; } void FRApp::Start(void) { TEString Name; TEVector Center; Name = "funracing.maps"; TEFileManager::GetFileManager()->AddArchive(Name); Name = "funracing.models"; TEFileManager::GetFileManager()->AddArchive(Name); Name = "funracing.textures"; TEFileManager::GetFileManager()->AddArchive(Name); Name = "Fun Racing"; m_pRenderer->SetWindowTitle(Name); m_pTimer->SetTimeFactor(0.0f); LoadConfig(); m_pRenderer->SetResolution(m_usScreenWidth, m_usScreenHeight, m_usScreenBpp); ApplyDetailSettings(); LoadRes(); m_pSoundDevice->SetVolume(m_fGeneralVolume); m_pTimer->SetTimeFactor(1.0f); if(m_bPlayIntro) { m_GameState = PLAYING_INTROS; FREngineLogo::Start(); FRGameLogo::Start(); } // make sure no outdated keydown messages arrive in main menu m_GameState = NOTREADY; m_pInputDevices->Update(); m_pEngine->ShowCursor(true); m_GameState = MAINMENU; } void FRApp::Update1(UInt32 ulDeltaT) { if((m_GameState == RACE || m_GameState == SERVERRACE || m_GameState == CLIENTRACE) && TEConsole::GetConsole()->GetState() == TE_CONSOLE_HIDE) UpdateRace1(ulDeltaT); } void FRApp::Update2(UInt32 ulDeltaT) { if((m_GameState == RACE || m_GameState == SERVERRACE || m_GameState == CLIENTRACE) && TEConsole::GetConsole()->GetState() == TE_CONSOLE_HIDE) UpdateRace2(ulDeltaT); } void FRApp::Render(void) { if(m_GameState == RACE || m_GameState == SERVERRACE || m_GameState == CLIENTRACE) { RenderRace(); } else if(m_GameState == MAINMENU) RenderMainMenu(); else if(m_GameState == OPTIONSMENU) RenderOptionsMenu(); else if(m_GameState == VIDEOMENU) RenderVideoMenu(); else if(m_GameState == AUDIOMENU) RenderAudioMenu(); else if(m_GameState == INPUTMENU1) RenderInputMenu1(); else if(m_GameState == INPUTMENU2) RenderInputMenu2(); else if(m_GameState == INPUTMENU3) RenderInputMenu3(); else if(m_GameState == CAREERMENU) RenderCareerMenu(); else if(m_GameState == CAREERRACEMENU) RenderCareerRaceMenu(); else if(m_GameState == QUICKRACEMENU) RenderQuickRaceMenu(); else if(m_GameState == NETWORKMENU) RenderNetworkMenu(); else if(m_GameState == SERVERMENU) RenderServerMenu(); else if(m_GameState == CLIENTMENU) RenderClientMenu(); else if(m_GameState == WAITINGFORCLIENTS) RenderWaitingForClients(); else if(m_GameState == WAITINGFORSERVER) RenderWaitingForServer(); else if(m_GameState == CREDITS) RenderCredits(); else if(m_GameState == STATISTIC) RenderStatistic(); } void FRApp::KeyDown(TEKeyState ulKey) { if(m_GameState == RACE || m_GameState == SERVERRACE || m_GameState == CLIENTRACE) { if(m_bShowAbortMenu) { if(m_GameState == SERVERRACE) { KeyDownInGameMenuServer(ulKey); return; } else if(m_GameState == CLIENTRACE) { KeyDownInGameMenuClient(ulKey); return; } } if(ulKey == TE_KEY_ESCAPE) { if(m_pCar->m_State != RACING && m_pCar->m_State != WAITING && m_GameState == RACE) { if(m_bCareerRace) { UInt32 ulCount, ulCount2, aulPos[4]; m_pCareer->ulCurrRace++; aulPos[0] = 0; aulPos[1] = 1; aulPos[2] = 2; aulPos[3] = 3; for(ulCount = 0; ulCount < 3; ulCount++) { for(ulCount2 = ulCount+1; ulCount2 < 4; ulCount2++) { bool bChange = false; bool bFin1 = m_apCars[aulPos[ulCount]]->m_State >= FINISHED1ST && m_apCars[aulPos[ulCount]]->m_State <= FINISHED4TH; bool bFin2 = m_apCars[aulPos[ulCount2]]->m_State >= FINISHED1ST && m_apCars[aulPos[ulCount2]]->m_State <= FINISHED4TH; TEAssert(m_apCars[aulPos[ulCount]]->m_State != m_apCars[aulPos[ulCount2]]->m_State); if(bFin1 && bFin2) { if(m_apCars[aulPos[ulCount]]->m_State > m_apCars[aulPos[ulCount2]]->m_State) bChange = true; } else if(bFin2) bChange = true; else if(!bFin1 && !bFin2) { if(m_apCars[aulPos[ulCount]]->m_State == DESTROYED && m_apCars[aulPos[ulCount2]]->m_State != DESTROYED) bChange = true; else if(m_apCars[aulPos[ulCount]]->m_ulLap < m_apCars[aulPos[ulCount2]]->m_ulLap) bChange = true; else if(m_apCars[aulPos[ulCount]]->m_ulLap == m_apCars[aulPos[ulCount2]]->m_ulLap) { if( (m_apCars[aulPos[ulCount]]->m_ulTrackNode-1 < m_apCars[aulPos[ulCount2]]->m_ulTrackNode-1)) bChange = true; else if(m_apCars[aulPos[ulCount]]->m_ulTrackNode == m_apCars[aulPos[ulCount2]]->m_ulTrackNode) { Float fDist1 = m_aTrackNodes[m_apCars[aulPos[ulCount]]->m_ulTrackNode].m_Plane.DistanceToPlane(m_apCars[aulPos[ulCount]]->m_Center); Float fDist2 = m_aTrackNodes[m_apCars[aulPos[ulCount2]]->m_ulTrackNode].m_Plane.DistanceToPlane(m_apCars[aulPos[ulCount2]]->m_Center); if(fDist1 > fDist2) bChange = true; } } } if(bChange) { UInt32 ulTmp = aulPos[ulCount]; aulPos[ulCount] = aulPos[ulCount2]; aulPos[ulCount2] = ulTmp; } } } for(ulCount = 0; ulCount < 4; ulCount++) m_pCareer->aulDriverPlacement[aulPos[ulCount]] = ulCount; for(ulCount = 0; ulCount < 4; ulCount++) { if(m_pCareer->aulDriverPlacement[ulCount] == 0) m_pCareer->aulDriverScore[ulCount] += 10; else if(m_pCareer->aulDriverPlacement[ulCount] == 1) m_pCareer->aulDriverScore[ulCount] += 8; else if(m_pCareer->aulDriverPlacement[ulCount] == 2) m_pCareer->aulDriverScore[ulCount] += 6; else m_pCareer->aulDriverScore[ulCount] += 4; } ExitRace(); if(m_pCareer->ulCurrRace < 10) SaveCareer(); m_GameState = STATISTIC; } else ExitRace(); } else { m_bShowAbortMenu = !m_bShowAbortMenu; if(m_GameState != RACE) m_pEngine->ShowCursor(true); } } else if(ulKey == TE_KEY_ENTER && m_bShowAbortMenu && m_GameState == RACE) ExitRace(); else if(ulKey == m_aulKeys[RESET] && m_pCar->m_State == RACING) { UInt32 ulTmp; ulTmp = m_pCar->m_ulTrackNode; if(ulTmp == 0) ulTmp = m_ulNumTrackNodes-1; else ulTmp--; if(ulTmp == 0) m_pCar->m_ulLap--; m_pCar->Reset(m_aTrackNodes[ulTmp].m_Position, m_aTrackNodes[ulTmp].m_Plane.m_Normal); if(m_GameState == CLIENTRACE) { ulTmp = FRCLIENTRESET; m_pNetworkManager->SendDataToServer(&ulTmp, sizeof(ulTmp)); } else if(m_GameState == SERVERRACE) { FRCarEnable Enable; Enable.ulMsgType = FRBLINKING; Enable.ucCar = 0; m_pNetworkManager->SendDataToAllClients(&Enable, sizeof(Enable)); } } else if(ulKey == m_aulKeys[SCREENSHOT]) { Char acTmp[128]; TEString Name; sprintf(acTmp, "%d",m_pTimer->GetRealTime()); Name.Set(acTmp); m_pRenderer->TakeScreenshot(Name); } else if(ulKey == m_aulKeys[CAMPOS]) { m_ulCurrCamPos++; if(m_ulCurrCamPos > 2) m_ulCurrCamPos = 0; m_fCamDelta= 0; } else if(ulKey == m_aulKeys[POWERUP]) { if(m_GameState == CLIENTRACE) { UInt32 ulTmp = FRCLIENTPOWERUP; m_pNetworkManager->SendDataToServer(&ulTmp, sizeof(ulTmp)); } else if(m_GameState == SERVERRACE) { FRCarEnable Enable; Enable.ulMsgType = FRENABLEPOWERUP; Enable.ucCar = 0; m_pNetworkManager->SendDataToAllClients(&Enable, sizeof(Enable)); m_pCar->EnablePowerUp(); } else m_pCar->EnablePowerUp(); } else if(ulKey == m_aulKeys[HORN]) { m_pCar->Horn(); if(m_GameState == CLIENTRACE) { UInt32 ulTmp = FRCLIENTHORN; m_pNetworkManager->SendDataToServer(&ulTmp, sizeof(ulTmp)); } else if(m_GameState == SERVERRACE) { FRCarEnable Enable; Enable.ulMsgType = FRENABLEHORN; Enable.ucCar = 0; m_pNetworkManager->SendDataToAllClients(&Enable, sizeof(Enable)); } } } else if(m_GameState == MAINMENU) KeyDownMainMenu(ulKey); else if(m_GameState == OPTIONSMENU) KeyDownOptionsMenu(ulKey); else if(m_GameState == VIDEOMENU) KeyDownVideoMenu(ulKey); else if(m_GameState == AUDIOMENU) KeyDownAudioMenu(ulKey); else if(m_GameState == INPUTMENU1) KeyDownInputMenu1(ulKey); else if(m_GameState == INPUTMENU2) KeyDownInputMenu2(ulKey); else if(m_GameState == INPUTMENU3) KeyDownInputMenu3(ulKey); else if(m_GameState == CAREERMENU) KeyDownCareerMenu(ulKey); else if(m_GameState == CAREERRACEMENU) KeyDownCareerRaceMenu(ulKey); else if(m_GameState == QUICKRACEMENU) KeyDownQuickRaceMenu(ulKey); else if(m_GameState == NETWORKMENU) KeyDownNetworkMenu(ulKey); else if(m_GameState == SERVERMENU) KeyDownServerMenu(ulKey); else if(m_GameState == CLIENTMENU) KeyDownClientMenu(ulKey); else if(m_GameState == STATISTIC) KeyDownStatistic(ulKey); } void FRApp::KeyUp(TEKeyState ulKey) { } void FRApp::MouseMovement(UInt32 ulPosX, UInt32 ulPosY, Int32 lMovX, Int32 lMovY, Char cWheel) { } void FRApp::JoystickMovement(Int32 lX, Int32 lY, Int32 lZ) { } void FRApp::Terminate(void) { } bool FRApp::ReceiveCustomEntity(TECustomEntity* pEntity) { TEEngineObject* pObj; Int32 lPos; if(pEntity->m_Name == "TrackNode") { lPos = (Int32) *pEntity->m_acData; if(lPos >= 0 && lPos < MAX_NODES) { m_aTempTrackNodes[lPos].m_Position = pEntity->m_Position; m_aTempTrackNodes[lPos].m_Plane = *pEntity->m_pPolygonList->GetPlanes(); m_aTempTrackNodes[lPos].m_BSphere.UpdateVolume(pEntity->m_pPolygonList, true); m_aTempTrackNodes[lPos].m_BSphere.SetData(pEntity->m_Position, 900.0f); m_ulNumTrackNodes++; } } else if(pEntity->m_Name == "AINode") { lPos = (Int32) *pEntity->m_acData; if(lPos >= 0 && lPos < MAX_NODES) { m_aTempAINodes[lPos].m_Position = pEntity->m_Position; m_aTempAINodes[lPos].m_fMaxSpeed = *((Float*)(pEntity->m_acData+4)); m_aTempAINodes[lPos].m_bHandbrake = *((bool*)(pEntity->m_acData+8)); m_ulNumAINodes++; } } else if(pEntity->m_Name == "StartPosition") { lPos = (Int32) *pEntity->m_acData; if(lPos >= 1 && lPos <= 4) { lPos = lPos-1; m_aStartPositions[lPos] = pEntity->m_Position; m_aStartRotations[lPos] = *((Float*)(pEntity->m_acData+4)); } } else if(pEntity->m_Name == "Barrier") { pObj = new FRBarrier(pEntity); TEEngine::GetEngine()->AddObjectToWorld(pObj); } else if(pEntity->m_Name == "PowerUp" && FRCar::ms_bPowerUpsEnabled) { pObj = new FRPowerUp(pEntity->m_Position); TEEngine::GetEngine()->AddObjectToWorld(pObj); } else if(pEntity->m_Name == "RoadSign" && m_Details != VERYLOW) { pObj = new FRRoadSign(pEntity); TEEngine::GetEngine()->AddObjectToWorld(pObj); } return false; } void FRApp::NewClientConnected(TEClient* pClient) { FRGameInfo GameInfo; m_apClients[m_ulNumClients] = pClient; m_ulNumClients++; GameInfo.ulMsgType = FRGAMEINFO; GameInfo.GameType = m_CurrGameType; GameInfo.ulTrack = m_ulCurrTrack; GameInfo.ulNumLaps = m_ulNumLapsForCurrRace; m_pNetworkManager->SendDataToClient(pClient->ulID, &GameInfo, sizeof(GameInfo)); } void FRApp::ClientDisconnected(TEClient* pClient) { TEString Msg = pClient->acName; TEClient* apClients[3]; FRCarName aClientCars[3]; UInt32 ulCount, ulIndex; if(m_GameState == WAITINGFORCLIENTS) { memcpy(apClients, m_apClients, sizeof(TEClient*)*3); memcpy(aClientCars, m_aClientCars, sizeof(FRCarName)*3); memset(m_apClients, 0, sizeof(TEClient*)*3); memset(m_aClientCars, 0, sizeof(FRCarName)*3); ulCount = ulIndex = 0; for(; ulCount < m_ulNumClients; ulCount++) { if(apClients[ulCount] != pClient) { m_apClients[ulIndex] = apClients[ulCount]; m_aClientCars[ulIndex] = aClientCars[ulCount]; ulIndex++; } } m_ulNumClients -= 1; } else { for(ulCount = 0; ulCount < m_ulNumClients; ulCount++) { if(m_apClients[ulCount] == pClient) m_apClients[ulCount] = NULL; } } Msg = Msg + TETranslator::GetTranslator()->Translate(" left the game"); TEConsole::GetConsole()->ConsoleMessage(Msg, TE_USER_ONLY); } void FRApp::DataFromClient(TEClient* pClient, Char* pData, UInt32 ulSize) { UInt32 ulTmp = *(UInt32*) pData; UInt32 ulClient = GetClientPos(pClient); FRClientCar* pCar; FRClientState* pState; FRCarEnable Enable; switch(ulTmp){ case FRCLIENTCAR: if(ulSize != sizeof(FRClientCar)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pCar = (FRClientCar*) pData; m_aClientCars[ulClient] = pCar->Car; break; case FRCLIENTSTATE: if(ulSize != sizeof(FRClientState)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pState = (FRClientState*) pData; m_apCars[1+ulClient]->SetPedal(pState->fGasPedal); m_apCars[1+ulClient]->SetSteeringWheel(pState->fSteeringWheel); m_apCars[1+ulClient]->SetHandbrake(pState->bHandbrake); break; case FRCLIENTRESET: if(ulSize != sizeof(UInt32)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } UInt32 ulTmp; ulTmp = m_apCars[1+ulClient]->m_ulTrackNode; if(ulTmp == 0) ulTmp = m_ulNumTrackNodes-1; else ulTmp--; if(ulTmp == 0) m_apCars[1+ulClient]->m_ulLap--; m_apCars[1+ulClient]->Reset(m_aTrackNodes[ulTmp].m_Position, m_aTrackNodes[ulTmp].m_Plane.m_Normal); Enable.ulMsgType = FRBLINKING; Enable.ucCar = (UChar) (1 + ulClient); m_pNetworkManager->SendDataToAllClients(&Enable, sizeof(Enable)); break; case FRCLIENTPOWERUP: if(ulSize != sizeof(UInt32)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } m_apCars[1+ulClient]->EnablePowerUp(); Enable.ulMsgType = FRENABLEPOWERUP; Enable.ucCar = (UChar) (1 + ulClient); m_pNetworkManager->SendDataToAllClients(&Enable, sizeof(Enable)); break; case FRCLIENTHORN: if(ulSize != sizeof(UInt32)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } m_apCars[1+ulClient]->Horn(); Enable.ulMsgType = FRENABLEHORN; Enable.ucCar = (UChar) (1 + ulClient); m_pNetworkManager->SendDataToAllClients(&Enable, sizeof(Enable)); break; case FRCLIENTREADY: if(ulSize != sizeof(UInt32)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } m_abClientReady[ulClient] = true; break; }; } void FRApp::ServerConnected(Char acServerName[32]) { m_bConnectedToServer = true; } void FRApp::ServerDisconnected(void) { m_bConnectedToServer = false; if(m_GameState == CLIENTRACE) { UnloadBSPFile(); m_GameState = MAINMENU; m_pNetworkManager->EndClient(); m_pEngine->ShowCursor(true); } } void FRApp::DataFromServer(Char* pData, UInt32 ulSize) { UInt32 ulMsgType = *(UInt32*) pData; UInt32 ulCount, *pulData; FRGameInfo* pInfo; FRPlayerInfo* pInfo2; FRCarUpdate* pUpdate; FRCarEnable* pEnable; FRCountdown* pCountdown; FRClientCar Car; TEString Str; switch(ulMsgType){ case FRGAMEINFO: if(ulSize != sizeof(FRGameInfo)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pInfo = (FRGameInfo*) pData; m_CurrGameType = pInfo->GameType; m_ulCurrTrack = pInfo->ulTrack; m_ulNumLapsForCurrRace = pInfo->ulNumLaps; m_bCareerRace = false; m_bShowAbortMenu = false; LoadCurrTrack(); Car.ulMsgType = FRCLIENTCAR; Car.Car = m_CurrCar; m_pNetworkManager->SendDataToServer(&Car, sizeof(Car)); ulCount = FRCLIENTREADY; m_pNetworkManager->SendDataToServer(&ulCount, sizeof(ulCount)); m_GameState = WAITINGFORSERVER; m_bConnectedToServer = true; m_pEngine->ShowCursor(true); break; case FRPLAYERINFO: if(ulSize != sizeof(FRPlayerInfo)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pInfo2 = (FRPlayerInfo*) pData; memset(m_apCars, 0, sizeof(FRCar*) * 4); for(ulCount = 0; ulCount < pInfo2->ulNumPlayers; ulCount++) { m_apCars[ulCount] = GetCar(pInfo2->aCars[ulCount], m_aStartPositions[3-ulCount], m_aStartRotations[3-ulCount]); m_apCars[ulCount]->m_Type = NETWORK; m_apCars[ulCount]->m_DriverName = pInfo2->aPlayerNames[ulCount]; m_pEngine->AddObjectToWorld(m_apCars[ulCount]); } TETextureManager::GetTextureManager()->ReleaseUnusedTextures(); TEModelManager::GetModelManager()->FreeUnusedModels(); TESoundManager::GetSoundManager()->FreeUnusedSounds(); m_pCar = m_apCars[pInfo2->ulOwnPos]; m_pEngine->ShowCursor(false); m_bShowAbortMenu = false; break; case FRCOUNTDOWN: if(ulSize != sizeof(FRCountdown)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pCountdown = (FRCountdown*) pData; m_ulCountdown = pCountdown->ucState; m_GameState = CLIENTRACE; break; case FRCARUPDATE: if(ulSize != sizeof(FRCarUpdate)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pUpdate = (FRCarUpdate*) pData; m_apCars[pUpdate->ucCar]->SetPedal(pUpdate->fGasPedal); m_apCars[pUpdate->ucCar]->SetSteeringWheel(pUpdate->fSteeringWheel); m_apCars[pUpdate->ucCar]->SetHandbrake(pUpdate->bHandbrake); m_apCars[pUpdate->ucCar]->m_lCurrentGear = pUpdate->lGear; m_apCars[pUpdate->ucCar]->m_lPowerUp = pUpdate->lPowerUp; m_apCars[pUpdate->ucCar]->m_Velocity = pUpdate->Velocity; m_apCars[pUpdate->ucCar]->m_State = pUpdate->State; m_apCars[pUpdate->ucCar]->m_ulLap = pUpdate->ulLap; if(m_apCars[pUpdate->ucCar]->m_Center != pUpdate->Pos || m_apCars[pUpdate->ucCar]->m_Rotation != pUpdate->Rotation) { TEAABoundingBox BBox; TEVector Min, Max; TEOBoundingBox* pBox = (TEOBoundingBox*) m_apCars[pUpdate->ucCar]->m_pBoundingVolume; m_apCars[pUpdate->ucCar]->m_Center = pUpdate->Pos; m_apCars[pUpdate->ucCar]->m_Rotation = pUpdate->Rotation; BBox = m_apCars[pUpdate->ucCar]->m_pModelRef->GetModelBBox(); BBox.GetData(Min, Max); pBox->SetData(m_apCars[pUpdate->ucCar]->m_Center, Min, Max, m_apCars[pUpdate->ucCar]->m_Rotation); m_apCars[pUpdate->ucCar]->UpdateVectors(); } break; case FRENABLEHORN: if(ulSize != sizeof(FRCarEnable)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pEnable = (FRCarEnable*) pData; m_apCars[pEnable->ucCar]->Horn(); break; case FRENABLEPOWERUP: if(ulSize != sizeof(FRCarEnable)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pEnable = (FRCarEnable*) pData; m_apCars[pEnable->ucCar]->EnablePowerUp(); break; case FRPLACES: if(ulSize != sizeof(UInt32)*5) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pulData = (UInt32*) pData; m_aulPosition[0] = pulData[1]; m_aulPosition[1] = pulData[2]; m_aulPosition[2] = pulData[3]; m_aulPosition[3] = pulData[4]; break; case FRBLINKING: if(ulSize != sizeof(FRCarEnable)) { TEString Error = "Network Message Size Incorrect"; TEAddErrorLog(Error); return; } pEnable = (FRCarEnable*) pData; m_apCars[pEnable->ucCar]->m_ulLastReset = m_pTimer->GetTime(); m_apCars[pEnable->ucCar]->m_Visibility = BLINKING; break; }; } void FRApp::UpdateRace1(UInt32 ulDeltaT) { if(m_pCar->m_State != RACING) return; Float fPedal, fWheel; bool bHandbrake; if(m_GameState == CLIENTRACE) { fPedal = m_pCar->m_fPedal; fWheel = m_pCar->m_fSteeringWheel; bHandbrake = m_pCar->m_bHandbrake; } if(m_pInputDevices->IsPressed(m_aulKeys[GAS])) m_pCar->SetPedal(1.0f); else if(m_pInputDevices->IsPressed(m_aulKeys[BRAKE])) m_pCar->SetPedal(-1.0f); else m_pCar->SetPedal(0.0f); if(m_pInputDevices->IsPressed(m_aulKeys[RIGHT])) m_pCar->SetSteeringWheel(1.0f); else if(m_pInputDevices->IsPressed(m_aulKeys[LEFT])) m_pCar->SetSteeringWheel(-1.0f); else m_pCar->SetSteeringWheel(0.0f); if(m_pInputDevices->IsPressed(m_aulKeys[HANDBRAKE])) m_pCar->SetHandbrake(true); else m_pCar->SetHandbrake(false); if(m_bUseJoystick) { Int32 lX, lY, lZ; Float fTmp; m_pInputDevices->GetJoystickAxis(lX, lY, lZ); fTmp = lX * m_fJoystickSensitivity * 0.001f; if(fTmp < -1.0f) fTmp = -1.0f; else if(fTmp > 1.0f) fTmp = 1.0f; else if(TEAbs(fTmp) <= 0.05f) fTmp = 0.0f; m_pCar->SetSteeringWheel(fTmp); if(m_JoystickAccel == YAXIS) { fTmp = -lY * m_fJoystickSensitivity * 0.001f; if(fTmp < -1.0f) fTmp = -1.0f; else if(fTmp > 1.0f) fTmp = 1.0f; else if(TEAbs(fTmp) <= 0.05f) fTmp = 0.0f; m_pCar->SetPedal(fTmp); } else if(m_JoystickAccel == ZAXIS) { fTmp = -lZ * m_fJoystickSensitivity * 0.001f; if(fTmp < -1.0f) fTmp = -1.0f; else if(fTmp > 1.0f) fTmp = 1.0f; else if(TEAbs(fTmp) <= 0.05f) fTmp = 0.0f; m_pCar->SetPedal(fTmp); } } if(m_GameState == CLIENTRACE) { if(fPedal != m_pCar->m_fPedal || fWheel != m_pCar->m_fSteeringWheel || bHandbrake != m_pCar->m_bHandbrake) { FRClientState State; State.ulMsgType = FRCLIENTSTATE; State.fGasPedal = m_pCar->m_fPedal; State.fSteeringWheel = m_pCar->m_fSteeringWheel; State.bHandbrake = m_pCar->m_bHandbrake; m_pNetworkManager->SendDataToServer(&State, sizeof(State)); } } m_pCar->m_bClip = true; } void FRApp::UpdateRace2(UInt32 ulDeltaT) { TECamera* pCam = m_pRenderer->GetCamera(); TEVector Center, Rot; TEMatrix3x3 MatRot; UInt16 usCount, usCmp; UInt32 ulTmp; Center = m_pCar->GetCenter(); Rot = m_pCar->GetRotation(); if(m_pCar->m_Visibility == INVISIBLE) m_pCar->m_Visibility = NORMAL; if(m_bCamAnimation && m_ulCurrCamPos != 0) { if(m_pCar->m_fSteeringWheel > 0.0f) { if(m_fCamDelta < 10.0f) { m_fCamDelta += CAM_SPEED * ulDeltaT * 0.001f; if(m_fCamDelta > 10.0f) m_fCamDelta = 10.0f; } } else if(m_pCar->m_fSteeringWheel < 0.0f) { if(m_fCamDelta > -10.0f) { m_fCamDelta -= CAM_SPEED * ulDeltaT * 0.001f; if(m_fCamDelta < -10.0f) m_fCamDelta = -10.0f; } } else if(m_fCamDelta != 0) { if(m_fCamDelta > 0.0f) { m_fCamDelta -= CAM_SPEED * ulDeltaT * 0.001f; if(m_fCamDelta < 0.0f) m_fCamDelta = 0.0f; } else if(m_fCamDelta < 0.0f) { m_fCamDelta += CAM_SPEED * ulDeltaT * 0.001f; if(m_fCamDelta > 0.0f) m_fCamDelta = 0.0f; } } } if(m_pInputDevices->IsNotPressed(m_aulKeys[LOOKBACK])) { switch(m_ulCurrCamPos){ case 0: Center.m_fY += m_pCar->m_CarSize.m_fY * 0.75f; Rot.m_fX = Rot.m_fZ = 0; Rot.m_fY = -Rot.m_fY; m_pCar->m_Visibility = INVISIBLE; m_pCar->m_bClip = false; break; case 1: MatRot.YRotationMatrixDeg(Rot.m_fY); Center = Center + MatRot * TEVector(0.0f, 25.0f, -65.0f); if(m_bCamAnimation && m_fCamDelta != 0) Center = Center + MatRot * TEVector(m_fCamDelta, 0.0f, 0.0f); Rot.m_fX = -12.5f; Rot.m_fY = -Rot.m_fY; Rot.m_fZ = 0; break; case 2: MatRot.YRotationMatrixDeg(Rot.m_fY); Center = Center + MatRot * TEVector(0.0f, 40.0f, -100.0f); if(m_bCamAnimation && m_fCamDelta != 0) Center = Center + MatRot * TEVector(m_fCamDelta, 0.0f, 0.0f); Rot.m_fX = -17.5f; Rot.m_fY = -Rot.m_fY; Rot.m_fZ = 0; break; }; } else { MatRot.YRotationMatrixDeg(Rot.m_fY); Center = Center + MatRot * TEVector(0.0f, m_pCar->m_CarSize.m_fY * 0.25f, -m_pCar->m_CarSize.m_fZ * 0.85f); Rot.m_fX = Rot.m_fZ = 0; Rot.m_fY = 180.0f - Rot.m_fY; m_pCar->m_Visibility = INVISIBLE; m_pCar->m_bClip = false; } pCam->SetPosition(Center); pCam->SetRotation(Rot); if(m_GameState == RACE || m_GameState == SERVERRACE) { UInt32 ulCars = 4; if(m_GameState == SERVERRACE) ulCars = 1 + m_ulNumClients; for(usCount = 0; usCount < ulCars; usCount++) { TEVector Center = m_apCars[usCount]->GetCenter(); if(m_aTrackNodes[m_apCars[usCount]->m_ulTrackNode].m_Plane.DistanceToPlane(Center) < 0 && m_aTrackNodes[m_apCars[usCount]->m_ulTrackNode].m_BSphere.IntersectsVolume(*(TEOBoundingBox*) m_apCars[usCount]->m_pBoundingVolume)) { m_apCars[usCount]->m_ulTrackNode++; if(m_apCars[usCount]->m_ulTrackNode >= m_ulNumTrackNodes) { m_apCars[usCount]->m_ulTrackNode = 0; } if(m_apCars[usCount]->m_ulTrackNode == 1) m_apCars[usCount]->m_ulLap++; } if(m_apCars[usCount]->m_Type == AI) DoAI(m_apCars[usCount]); if( (m_apCars[usCount]->m_State >= FINISHED1ST && m_apCars[usCount]->m_State <= FINISHED4TH && m_apCars[usCount]->m_ulTrackNode > 0) || m_apCars[usCount]->m_State == KO || m_apCars[usCount]->m_State == DESTROYED) { if(m_apCars[usCount]->m_Velocity.GetLength() * 0.36f > 35 && m_apCars[usCount]->m_lCurrentGear > REVERSE_GEAR && m_apCars[usCount]->m_Velocity.DotProduct(m_apCars[usCount]->m_Forward) >= 0) { m_apCars[usCount]->SetPedal(-1.0f); m_apCars[usCount]->m_lCurrentGear = SECOND_GEAR; } else { m_apCars[usCount]->SetPedal(0.0f); m_apCars[usCount]->m_lCurrentGear = NEUTRAL_GEAR; m_apCars[usCount]->m_fCurrentRPM = 1000.0f; m_apCars[usCount]->m_Velocity = TEVector(0.0f, 0.0f, 0.0f); m_apCars[usCount]->m_fElasticity = 0.3f; m_apCars[usCount]->m_fFrictionFactor = 0.5f; } m_apCars[usCount]->SetHandbrake(true); m_apCars[usCount]->SetSteeringWheel(0.0f); m_apCars[usCount]->m_fBrakeEfficiency = 25.0f; } } for(usCount = 0; usCount < ulCars-1; usCount++) { if(m_apCars[m_aulPosition[usCount]]->m_State == RACING || m_apCars[m_aulPosition[usCount]]->m_State == DESTROYED) { for(usCmp = usCount+1; usCmp < ulCars; usCmp++) { if(m_apCars[m_aulPosition[usCmp]]->m_State == RACING) { UInt32 ulLap1, ulLap2; ulLap1 = m_apCars[m_aulPosition[usCmp]]->m_ulLap; ulLap2 = m_apCars[m_aulPosition[usCount]]->m_ulLap; if(m_apCars[m_aulPosition[usCmp]]->m_ulTrackNode == 0) ulLap1++; if(m_apCars[m_aulPosition[usCount]]->m_ulTrackNode == 0) ulLap2++; if(ulLap1 > ulLap2 || (ulLap1 == ulLap2 && m_apCars[m_aulPosition[usCmp]]->m_ulTrackNode > m_apCars[m_aulPosition[usCount]]->m_ulTrackNode) || m_apCars[m_aulPosition[usCount]]->m_State == DESTROYED) { ulTmp = m_aulPosition[usCmp]; m_aulPosition[usCmp] = m_aulPosition[usCount]; m_aulPosition[usCount] = ulTmp; } else if(ulLap1 == ulLap2 && m_apCars[m_aulPosition[usCmp]]->m_ulTrackNode == m_apCars[m_aulPosition[usCount]]->m_ulTrackNode) { Float fDist1, fDist2; fDist1 = TEAbs(m_aTrackNodes[m_apCars[m_aulPosition[usCmp]]->m_ulTrackNode].m_Plane.DistanceToPlane(m_apCars[m_aulPosition[usCmp]]->m_Center)); fDist2 = TEAbs(m_aTrackNodes[m_apCars[m_aulPosition[usCount]]->m_ulTrackNode].m_Plane.DistanceToPlane(m_apCars[m_aulPosition[usCount]]->m_Center)); if(fDist1 < fDist2) { ulTmp = m_aulPosition[usCmp]; m_aulPosition[usCmp] = m_aulPosition[usCount]; m_aulPosition[usCount] = ulTmp; } } } } } } for(usCount = 0; usCount < ulCars; usCount++) { if(m_apCars[usCount]->m_ulLap == m_ulNumLapsForCurrRace+1) { if(m_aulPosition[0] == usCount) m_apCars[usCount]->m_State = FINISHED1ST; else if(m_aulPosition[1] == usCount) m_apCars[usCount]->m_State = FINISHED2ND; else if(m_aulPosition[2] == usCount) m_apCars[usCount]->m_State = FINISHED3RD; else if(m_aulPosition[3] == usCount) m_apCars[usCount]->m_State = FINISHED4TH; m_apCars[usCount]->m_ulLap = m_ulNumLapsForCurrRace; } if(m_CurrGameType == KNOCKOUT || m_CurrGameType == POWERUPKO) { if( (m_apCars[usCount]->m_ulLap == m_ulNumLapsForCurrRace-1 && m_aulPosition[3] == usCount) || (m_apCars[usCount]->m_ulLap == m_ulNumLapsForCurrRace && m_aulPosition[2] == usCount) || m_apCars[usCount]->m_State == FINISHED2ND) { if(m_apCars[usCount]->m_State == FINISHED2ND) m_apCars[usCount]->m_ulLap = m_ulNumLapsForCurrRace+1; m_apCars[usCount]->m_State = KO; } } if(m_CurrGameType == RACETODEATH && m_apCars[usCount]->m_State == RACING && (m_apCars[usCount]->m_lPowerUpInfluence == POWERUP_MINE || m_apCars[usCount]->m_lPowerUpInfluence == POWERUP_ROCKET)) m_apCars[usCount]->m_State = DESTROYED; } if(m_CurrGameType == RACETODEATH) { usCmp = 0; for(usCount = 0; usCount < ulCars; usCount++) { if(m_apCars[usCount]->m_State == DESTROYED) usCmp++; else ulTmp = usCount; } if(usCmp == ulCars-1 && m_apCars[ulTmp]->m_State == RACING) m_apCars[ulTmp]->m_State = FINISHED1ST; } } UInt32 ulSpeed = (UInt32) m_pCar->GetSpeedKMH(); UInt32 ulDelta = TEAbs((Int32) m_ulTachoSpeed - (Int32) ulSpeed); if(ulDelta <= 3) m_ulTachoSpeed = ulSpeed; else { if(ulSpeed > m_ulTachoSpeed) m_ulTachoSpeed += 3; else if(ulSpeed < m_ulTachoSpeed) m_ulTachoSpeed -= 3 * (ulDelta / 10); } if(ulSpeed <= 3) m_ulTachoSpeed = 0; if(m_GameState == SERVERRACE) { FRCarUpdate Update; UInt32 aulPos[5]; Update.ulMsgType = FRCARUPDATE; for(usCount = 0; usCount < m_ulNumClients+1; usCount++) { Update.ucCar = (UChar) usCount; Update.fGasPedal = m_apCars[usCount]->m_fPedal; Update.fSteeringWheel = m_apCars[usCount]->m_fSteeringWheel; Update.bHandbrake = m_apCars[usCount]->m_bHandbrake; Update.lGear = m_apCars[usCount]->m_lCurrentGear; Update.lPowerUp = m_apCars[usCount]->m_lPowerUp; Update.Pos = m_apCars[usCount]->m_Center; Update.Rotation = m_apCars[usCount]->m_Rotation; Update.Velocity = m_apCars[usCount]->m_Velocity; Update.State = m_apCars[usCount]->m_State; Update.ulLap = m_apCars[usCount]->m_ulLap; m_pNetworkManager->SendDataToAllClients(&Update, sizeof(Update)); } aulPos[0] = FRPLACES; aulPos[1] = m_aulPosition[0]; aulPos[2] = m_aulPosition[1]; aulPos[3] = m_aulPosition[2]; aulPos[4] = m_aulPosition[3]; m_pNetworkManager->SendDataToAllClients(aulPos, sizeof(UInt32)*5); } } void FRApp::RenderRace(void) { Char acInfo[128]; UInt16 usCount; TEString Text; m_pRenderer->EnableBlending(); m_pRenderer->SetBlendingState(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); if(m_ulCountdown != 0) { UInt32 ulTime = m_pTimer->GetElapsedTime(m_ulCountdown); UChar ucState = 0; if(m_GameState != CLIENTRACE) { UInt32 ulTime = m_pTimer->GetElapsedTime(m_ulCountdown); if(ulTime <= 1000) ucState = 1; else if(ulTime <= 2000) ucState = 2; else if(ulTime <= 3000) ucState = 3; else if(ulTime <= 3500) ucState = 4; else if(m_GameState == SERVERRACE && ulTime <= 4000) ucState = 0; else m_ulCountdown = 0; if(m_GameState == SERVERRACE) { FRCountdown Msg; Msg.ulMsgType = FRCOUNTDOWN; Msg.ucState = ucState; m_pNetworkManager->SendDataToAllClients(&Msg, sizeof(Msg)); } } else ucState = (UChar) m_ulCountdown; if(ucState == 1) { m_pRenderer->SetAmbient(100, 0, 0, 250); sprintf(acInfo,"3"); m_pRenderer->DrawText(m_usScreenWidth/2-14, m_usScreenHeight/2-16, 32, acInfo); } else if(ucState == 2) { m_pRenderer->SetAmbient(200, 0, 0, 250); sprintf(acInfo,"2"); m_pRenderer->DrawText(m_usScreenWidth/2-14, m_usScreenHeight/2-16, 32, acInfo); } else if(ucState == 3) { m_pRenderer->SetAmbient(220, 220, 0, 250); sprintf(acInfo,"1"); m_pRenderer->DrawText(m_usScreenWidth/2-14, m_usScreenHeight/2-16, 32, acInfo); } else if(ucState == 4) { ulTime = m_pTimer->GetTime(); for(UInt16 usCount = 0; usCount < 4; usCount++) { if(m_apCars[usCount] == NULL) break; m_apCars[usCount]->m_State = RACING; m_apCars[usCount]->m_ulLastAINodeChange = ulTime; } m_pRenderer->SetAmbient(0, 150, 0, 250); sprintf(acInfo,"START!"); m_pRenderer->DrawText(m_usScreenWidth/2-81, m_usScreenHeight/2-16, 32, acInfo); } } else if(m_pCar->m_State >= FINISHED1ST && m_pCar->m_State <= FINISHED4TH) { m_pRenderer->SetAmbient(200, 0, 0, 250); if(m_pCar->m_State == FINISHED1ST) Text = TETranslator::GetTranslator()->Translate("YOU WIN!"); else if(m_pCar->m_State == FINISHED2ND) Text = TETranslator::GetTranslator()->Translate("Second Place"); else if(m_pCar->m_State == FINISHED3RD) Text = TETranslator::GetTranslator()->Translate("Third Place"); else if(m_pCar->m_State == FINISHED4TH) Text = TETranslator::GetTranslator()->Translate("Last Place"); m_pRenderer->DrawText(m_usScreenWidth/2 - (UInt16) (Text.GetLength() * 13.6f), m_usScreenHeight/2-16, 32, Text); } else if(m_pCar->m_State == DESTROYED) { m_pRenderer->SetAmbient(200, 0, 0, 250); Text = TETranslator::GetTranslator()->Translate("CAR DESTROYED!"); m_pRenderer->DrawText(m_usScreenWidth/2 - (UInt16) (Text.GetLength() * 13.6f), m_usScreenHeight/2-16, 32, Text); } else if(m_pCar->m_State == KO) { m_pRenderer->SetAmbient(200, 0, 0, 250); Text = "K.O."; m_pRenderer->DrawText(m_usScreenWidth/2 - (UInt16) (Text.GetLength() * 13.6f), m_usScreenHeight/2-16, 32, Text); } else { m_pRenderer->SetAmbient(0, 0, 255, 250); if(m_pCar->m_ulLap == 0) sprintf(acInfo, "1/%d", m_ulNumLapsForCurrRace); else sprintf(acInfo, "%d/%d", m_pCar->m_ulLap, m_ulNumLapsForCurrRace); Text = TETranslator::GetTranslator()->Translate("Lap:"); Text = Text + acInfo; m_pRenderer->DrawText(0, 0, 16, Text); } if(m_bShowAbortMenu) { if(m_GameState == SERVERRACE) RenderInGameMenuServer(); else if(m_GameState == CLIENTRACE) RenderInGameMenuClient(); else { m_pRenderer->SetAmbient(0, 0, 200, 250); Text = TETranslator::GetTranslator()->Translate("Press ESCAPE to continue race."); m_pRenderer->DrawText(m_usScreenWidth/2 - (UInt16) (Text.GetLength() * 6.8f), m_usScreenHeight/2-16, 16, Text); Text = TETranslator::GetTranslator()->Translate("Press ENTER to go to main menu."); m_pRenderer->DrawText(m_usScreenWidth/2 - (UInt16) (Text.GetLength() * 6.8f), m_usScreenHeight/2, 16, Text); } } if(m_pCar->m_State != RACING && m_pCar->m_State != WAITING && m_GameState == RACE) { m_pRenderer->SetAmbient(0, 0, 200, 250); if(!m_bCareerRace) Text = TETranslator::GetTranslator()->Translate("Press ESCAPE to go to main menu"); else Text = TETranslator::GetTranslator()->Translate("Press ESCAPE to continue"); m_pRenderer->DrawText(m_usScreenWidth/2 - (UInt16) (Text.GetLength() * 6.8f), 0, 16, Text); } m_pRenderer->SetAmbient(0, 0, 255, 250); #if TE_IS_DEBUG_VERSION == 1 sprintf(acInfo, "FPS: %d", m_pRenderer->GetFPS()); m_pRenderer->DrawText(0, m_usScreenHeight - 24, 16, acInfo); #endif for(usCount = 0; usCount < 4; usCount++) { if(m_apCars[m_aulPosition[usCount]] == NULL || m_apCars[m_aulPosition[usCount]]->m_State == KO || m_apCars[m_aulPosition[usCount]]->m_State == WAITING) continue; if(usCount == 0) Text = "1: "; else if(usCount == 1) Text = "2: "; else if(usCount == 2) Text = "3: "; else if(usCount == 3) Text = "4: "; Text = Text + m_apCars[m_aulPosition[usCount]]->m_DriverName; m_pRenderer->DrawText(0, 25 + 20 * usCount, 16, Text); } m_pRenderer->DisableBlending(); if(m_bShowTacho) RenderTacho(); RenderPowerUpIcon(m_pCar->m_lPowerUp); if(m_bUseMirror) RenderMirror(); } void FRApp::DoAI(FRCar* pCar) { TEMatrix3x3 MatRot; TEVector Center = pCar->GetCenter(); TEVector Rot = pCar->GetRotation(); MatRot.YRotationMatrixDeg(-Rot.m_fY); TEVector Forward = pCar->GetVelocity(); TEVector Diff = Center - m_aAINodes[pCar->m_ulAINode].m_Position; Float fSpeed, fD; UInt32 ulTmp, ulTime = TETimer::GetTimer()->GetTime();; fSpeed = pCar->GetSpeedKMH(); pCar->SetHandbrake(false); pCar->SetPedal(1.0f); if(fSpeed > (m_aAINodes[pCar->m_ulAINode].m_fMaxSpeed * pCar->m_fAIEfficiency) + 40) { if(m_aAINodes[pCar->m_ulAINode].m_bHandbrake && fSpeed > 100) pCar->SetHandbrake(true); else pCar->SetPedal(-1.0f); } // else if(fSpeed >= (m_aAINodes[pCar->m_ulAINode].m_fMaxSpeed * pCar->m_fAIEfficiency)) // pCar->SetPedal(0.9f); // else pCar->SetPedal(1.0f); Diff.m_fY = Forward.m_fY = 0; fD = Diff.GetLength(); Diff = Diff * MatRot; Forward = Forward * MatRot; Diff.Normalize(); Forward.Normalize(); if(fD < 150.0f) { pCar->m_ulAINode++; if(pCar->m_ulAINode >= m_ulNumAINodes) pCar->m_ulAINode = 0; pCar->m_ulLastAINodeChange = ulTime; } // if(m_aAINodes[pCar->m_ulAINode].m_bHandbrake && fSpeed > 100) // pCar->SetHandbrake(true); // else pCar->SetHandbrake(false); if(pCar->m_lPowerUpInfluence == POWERUP_OIL) { if(fSpeed > 20.0f) { if(pCar->m_ulPowerUpEndTime - m_pTimer->GetTime() < 700) { pCar->SetHandbrake(true); if(pCar->m_lCurrentGear != REVERSE_GEAR) pCar->SetPedal(-1.0f); else pCar->SetPedal(1.0f); } else pCar->SetPedal(0.0f); } else { pCar->SetHandbrake(false); pCar->SetPedal(0.5f); } } if(fSpeed > 0) { if(Diff.m_fX > 0.15f) { pCar->SetSteeringWheel(-1.0f); } else if(Diff.m_fX < -0.15f) { pCar->SetSteeringWheel(1.0f); } else pCar->SetSteeringWheel(0.0f); } else pCar->SetSteeringWheel(0.0f); if(pCar->m_lPowerUp != -1) { if(pCar->m_lPowerUp == POWERUP_N2O) pCar->EnablePowerUp(); else if(pCar->m_lPowerUp == POWERUP_ROCKET) { TEVector Dir = pCar->m_Forward * 750.0f * pCar->m_fAIEfficiency; TEClipInfo Info; if(m_pEngine->RayClipsInWorld(pCar->m_Center, Dir, Info, pCar) && TEIsDerivedFromClass(FRCar, Info.pObject)) pCar->EnablePowerUp(); } else { TEVector Dir = pCar->m_Forward * (-250.0f - 75.0f * pCar->m_fAIEfficiency); TEClipInfo Info; if(m_pEngine->RayClipsInWorld(pCar->m_Center, Dir, Info, pCar) && TEIsDerivedFromClass(FRCar, Info.pObject)) pCar->EnablePowerUp(); } } if(ulTime - pCar->m_ulLastAINodeChange > 20000 && pCar->m_State == RACING) { ulTmp = pCar->m_ulAINode; pCar->m_ulLastAINodeChange = ulTime; if(ulTmp == 0) ulTmp = m_ulNumTrackNodes-1; else ulTmp--; Forward = m_aAINodes[ulTmp].m_Position - m_aAINodes[pCar->m_ulAINode].m_Position; Forward.Normalize(); pCar->Reset(m_aAINodes[ulTmp].m_Position, Forward); } } FRCar* FRApp::GetAICar(TEVector &rCenter, Float fInitYRot, Int32 &rlAI1, Int32 &rlAI2) { Int32 lDriver = TERandM(25)-1; FRCar* pCar; while(rlAI1 == lDriver || rlAI2 == lDriver) lDriver = TERandM(25)-1; if(rlAI1 == -1) rlAI1 = lDriver; else if(rlAI2 == -1) rlAI2 = lDriver; pCar = GetCar(ms_aOpponents[lDriver].m_Car, rCenter, fInitYRot); pCar->m_DriverName = ms_aOpponents[lDriver].m_Name; pCar->m_bAIUsesHorn = ms_aOpponents[lDriver].m_bUsesHorn; pCar->m_fAIEfficiency = ms_aOpponents[lDriver].m_fAIEfficiency; if(pCar->m_fRotFactor < 120.0f) pCar->m_fRotFactor = 120.0f; return pCar; } void FRApp::RenderTacho() { Float fAngle, fX, fY; if(m_ulTachoSpeed > 200) m_ulTachoSpeed = 200; fAngle = m_ulTachoSpeed * 0.9f; // 0░ = 0 km/h 180░ = 200 km/h fY = TESinDeg(fAngle) * 0.08f; fX = TECosDeg(fAngle) * 0.08f; m_pRenderer->SetTexture(m_pTacho); m_pRenderer->EnableBlending(); m_pRenderer->SetBlendingState(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); m_pRenderer->SetAmbient(255, 255, 255, 255); m_pRenderer->DrawRectanglef(0.8f, 0.875f, 0.98f, 0.975f); m_pRenderer->DisableBlending(); m_pRenderer->SetTexture(NULL); m_pRenderer->SetAmbient(255, 0, 0); m_pRenderer->DrawLinef(0.89f-fX, 0.97f-fY, 0.89f, 0.97f, 2.0f); } void FRApp::RenderPowerUpIcon(Int32 lPowerUp) { if(lPowerUp > 3 || lPowerUp < 0) return; m_pRenderer->EnableBlending(); m_pRenderer->SetTexture(m_apPowerUpIcons[lPowerUp]); m_pRenderer->SetBlendingState(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); m_pRenderer->SetAmbient(255, 255, 255, 255); m_pRenderer->DrawRectangle(m_usScreenWidth-64, 0, m_usScreenWidth, 64); m_pRenderer->SetAmbient(0, 0, 200, 250); m_pRenderer->DrawText(m_usScreenWidth-154, 20, 16, "POWERUP"); // hardcoded translation to improve performance if(m_Lang == GERMAN) m_pRenderer->DrawText(m_usScreenWidth-158, 36, 14, "VERF▄GBAR"); else m_pRenderer->DrawText(m_usScreenWidth-158, 36, 14, "AVAILABLE"); m_pRenderer->DisableBlending(); } void FRApp::RenderMirror(void) { TECamera* pCam = m_pRenderer->GetCamera(); TECamera Tmp = *pCam; TEVector* pPos = pCam->GetPositionPointer(); TEVector* pRot = pCam->GetRotationPointer(); UInt16 usX = (UInt16) ((m_usScreenWidth - m_usMirrorWidth) * 0.5f); UInt16 usY = MIRROR_POS; FRCarVisibility Vis; bool bDecals = m_pEngine->GetDecalUse(); bool bDynLights = m_pEngine->GetDynamicLightUse(); bool bRefl = m_pEngine->GetReflectionUse(); TEShadowMethod Shadow = m_pEngine->GetShadowMethod(); m_pRenderer->SetTexture(NULL); m_pRenderer->SetAmbient(0, 0, 0); m_pRenderer->DrawRectangle(usX - 5, usY - 5, usX + m_usMirrorWidth + 5, usY + m_usMirrorHeight + 5); *pPos = m_pCar->m_pBoundingVolume->GetCenter() - m_pCar->m_Forward * m_pCar->m_CarSize.m_fZ * 0.5f; pPos->m_fY += m_pCar->m_CarSize.m_fY * 0.25f; pRot->m_fX = pRot->m_fZ = 0.0f; pRot->m_fY = 180.0f - m_pCar->m_Rotation.m_fY; pCam->SetPerspective(30.0f, (Float) m_usMirrorWidth / (Float) m_usMirrorHeight, Tmp.GetZNear(), Tmp.GetZFar()); pCam->UpdateCamera(); Vis = m_pCar->m_Visibility; m_pCar->m_Visibility = INVISIBLE; m_pEngine->SetDecalUse(false); m_pEngine->SetDynamicLightUse(false); m_pEngine->SetReflectionUse(false); m_pEngine->SetShadowMethod(SHADOW_NONE); m_pRenderer->SetViewport(usX, usY, m_usMirrorWidth, m_usMirrorHeight); m_pRenderer->ClearZBuffer(); m_pRenderer->ResetWorld(); m_pRenderer->ScaleWorld(-1.0f, 1.0f, 1.0f); m_pRenderer->ReverseVertexOrder(true); m_pRenderer->RotateWorldDeg(pRot->m_fX, pRot->m_fY, pRot->m_fZ); m_pRenderer->TransformWorld(-pPos->m_fX, -pPos->m_fY, -pPos->m_fZ); RenderWorld(); m_pCar->m_Visibility = Vis; *pCam = Tmp; m_pRenderer->SetViewport(0, 0, m_usScreenWidth, m_usScreenHeight); m_pRenderer->ReverseVertexOrder(false); m_pEngine->SetDecalUse(bDecals); m_pEngine->SetDynamicLightUse(bDynLights); m_pEngine->SetReflectionUse(bRefl); m_pEngine->SetShadowMethod(Shadow); } void FRApp::LoadRes(void) { TETextureManager* pTex = TETextureManager::GetTextureManager(); TEString Name, Pak; UChar aucColorkey[] = {0, 0, 255}; UInt32 ulCount; Pak = "HUD"; Name = "tacho"; m_pTacho = pTex->GetTexture(Name, Pak, false, aucColorkey); Name = "N2O"; m_apPowerUpIcons[0] = pTex->GetTexture(Name, Pak, false, aucColorkey); Name = "rocket"; m_apPowerUpIcons[1] = pTex->GetTexture(Name, Pak, false, aucColorkey); Name = "mine"; m_apPowerUpIcons[2] = pTex->GetTexture(Name, Pak, false, aucColorkey); Name = "oil"; m_apPowerUpIcons[3] = pTex->GetTexture(Name, Pak, false, aucColorkey); Pak = "menu"; Name = "background"; m_pMenuBackground = pTex->GetTexture(Name, Pak, false); Pak = "tracks"; for(ulCount = 0; ulCount < NUM_TRACKS; ulCount++) { Name = ms_aacTrackNames[ulCount]; m_apTrackImages[ulCount] = pTex->GetTexture(Name, Pak, false); } } void FRApp::LoadCurrTrack(void) { TEString Tmp = TETranslator::GetTranslator()->Translate("Loading..."); m_pRenderer->SetAmbient(255,255,255,255); m_pRenderer->SetTexture(m_pMenuBackground); m_pRenderer->DrawRectanglef(0.0f, 0.0f, 1.0f, 1.0f); m_pRenderer->SetAmbient(0,0,200,255); m_pRenderer->DrawText(m_usScreenWidth / 2 - (UInt32) (Tmp.GetLength() * 6.8f), m_usScreenHeight / 2 - 8, 16, Tmp); m_pRenderer->DisplayBackBuffer(); m_ulNumTrackNodes = 0; m_aTempTrackNodes = new FRTrackNode[MAX_NODES]; m_ulNumAINodes = 0; m_aTempAINodes = new FRAINode[MAX_NODES]; if(m_CurrGameType == NORMALRACE || m_CurrGameType == KNOCKOUT) FRCar::ms_bPowerUpsEnabled = false; else FRCar::ms_bPowerUpsEnabled = true; Tmp = ms_aacTrackNames[m_ulCurrTrack]; Tmp = Tmp + ".bsp"; UnloadBSPFile(); LoadBSPFile(Tmp); SafeDeleteA(m_aTrackNodes); SafeDeleteA(m_aAINodes); m_aTrackNodes = new FRTrackNode[m_ulNumTrackNodes]; m_aAINodes = new FRAINode[m_ulNumAINodes]; memcpy(m_aTrackNodes, m_aTempTrackNodes, sizeof(FRTrackNode)*m_ulNumTrackNodes); memcpy(m_aAINodes, m_aTempAINodes, sizeof(FRAINode)*m_ulNumAINodes); SafeDeleteA(m_aTempTrackNodes); SafeDeleteA(m_aTempAINodes); if(m_Details == LOW || m_Details == VERYLOW) { TEEngineObject *pTmp, *pBuf; pTmp = m_pEngine->GetObjectsInWorld(); pBuf = NULL; while(pTmp != NULL) { // remove TEModelObjects to improve performance if(TEIsTypeOfClass(TEModelObject, pTmp)) pBuf = pTmp; pTmp = pTmp->m_pNext; SafeDelete(pBuf); } // No ParticleFX to improve performance m_pEngine->FreeAllParticleSystems(); } } void FRApp::StartRace(void) { Int32 lNumTracks, lAI1, lAI2; Char acTmp[32]; TEString Name; if(m_pBackgroundMusic != NULL) { m_pBackgroundMusic->Stop(); SafeDelete(m_pBackgroundMusic); } switch(m_Music){ case DEFAULT: sprintf(acTmp, "music%d.ogg", TERandM(4)); Name = acTmp; m_pBackgroundMusic = TESoundManager::GetSoundManager()->GetSound(Name); m_pBackgroundMusic->Play(TESOUND_LOOP, m_fGeneralVolume * m_fMusicVolume); break; case FROMCD: lNumTracks = m_pCDPlayer->GetNumberOfTracks(); if(lNumTracks > 0) m_pCDPlayer->Play(TERandM(lNumTracks)-1); break; }; lAI1 = lAI2 = -1; m_apCars[0] = GetAICar(m_aStartPositions[0], m_aStartRotations[0], lAI1, lAI2); m_pEngine->AddObjectToWorld(m_apCars[0]); m_apCars[1] = GetAICar(m_aStartPositions[1], m_aStartRotations[1], lAI1, lAI2); m_pEngine->AddObjectToWorld(m_apCars[1]); m_apCars[2] = GetAICar(m_aStartPositions[2], m_aStartRotations[2], lAI1, lAI2); m_pEngine->AddObjectToWorld(m_apCars[2]); m_apCars[3] = m_pCar = GetCar(m_CurrCar, m_aStartPositions[3], m_aStartRotations[3]); m_pCar->m_Type = LOCAL; m_pCar->m_DriverName = m_PlayerName; m_pEngine->AddObjectToWorld(m_pCar); TETextureManager::GetTextureManager()->ReleaseUnusedTextures(); TEModelManager::GetModelManager()->FreeUnusedModels(); TESoundManager::GetSoundManager()->FreeUnusedSounds(); m_aulPosition[0] = 0; m_aulPosition[1] = 1; m_aulPosition[2] = 2; m_aulPosition[3] = 3; m_fCamDelta = 0; m_ulTachoSpeed = 0; m_pEngine->ShowCursor(false); m_ulCountdown = m_pTimer->GetTime(); m_bShowAbortMenu = false; } void FRApp::ExitRace(void) { UnloadBSPFile(); m_pEngine->ShowCursor(true); m_bShowAbortMenu = false; if(m_pBackgroundMusic != NULL && m_pBackgroundMusic->IsPlaying()) { m_pBackgroundMusic->Stop(); SafeDelete(m_pBackgroundMusic); } else if(m_Music == FROMCD) m_pCDPlayer->Stop(); if(m_GameState == SERVERRACE) m_pNetworkManager->EndServer(); else if(m_GameState == CLIENTRACE) m_pNetworkManager->EndClient(); m_GameState = MAINMENU; } void FRApp::LoadConfig(void) { FILE* pFile = fopen("frconfig.dat", "rb"); TETranslator *pTrans = TETranslator::GetTranslator(); TEString Language; TEString LangFile = "strings.txt"; UInt32 ulSize; Char* acName; if(pFile == NULL) { m_usScreenWidth = 640; m_usScreenHeight = 480; m_usScreenBpp = 16; m_bPlayIntro = true; m_bShowTacho = false; m_bCamAnimation = true; m_bUseMirror = true; m_Lang = ENGLISH; m_Details = MEDIUM; m_Music = DEFAULT; m_fGeneralVolume = 0.8f; m_fMusicVolume = 2.5f; m_bUseJoystick = false; m_JoystickAccel = YAXIS; m_fJoystickSensitivity = 1.0f; m_bBonusCarAvailable = false; m_ulCurrCamPos = 1; m_ulCurrTrack = 0; m_ulNumLaps = 4; m_CurrGameType = NORMALRACE; m_CurrCar = HUMMER; m_PlayerName = "Trainee"; m_usNetPort = 2000; m_IP.aucAddress[0] = 192; m_IP.aucAddress[1] = 168; m_IP.aucAddress[2] = 0; m_IP.aucAddress[3] = 1; m_aulKeys[GAS] = TE_KEY_UP; m_aulKeys[BRAKE] = TE_KEY_DOWN; m_aulKeys[LEFT] = TE_KEY_LEFT; m_aulKeys[RIGHT] = TE_KEY_RIGHT; m_aulKeys[HANDBRAKE] = TE_KEY_SPACE; m_aulKeys[HORN] = TE_KEY_ENTER; m_aulKeys[POWERUP] = TE_KEY_CTRL; m_aulKeys[RESET] = TE_KEY_R; m_aulKeys[CAMPOS] = TE_KEY_C; m_aulKeys[LOOKBACK] = TE_KEY_BACKSPACE; m_aulKeys[SCREENSHOT] = TE_KEY_F12; } else { fread(&m_usScreenWidth, sizeof(UInt16), 1, pFile); fread(&m_usScreenHeight, sizeof(UInt16), 1, pFile); fread(&m_usScreenBpp, sizeof(UInt16), 1, pFile); fread(&m_bPlayIntro, sizeof(bool), 1, pFile); fread(&m_bShowTacho, sizeof(bool), 1, pFile); fread(&m_bCamAnimation, sizeof(bool), 1, pFile); fread(&m_bUseMirror, sizeof(bool), 1, pFile); fread(&m_Lang, sizeof(FRLanguage), 1, pFile); fread(&m_Details, sizeof(FRDetailLevel), 1, pFile); fread(&m_Music, sizeof(FRBackgroundMusic), 1, pFile); fread(&m_fGeneralVolume, sizeof(Float), 1, pFile); fread(&m_fMusicVolume, sizeof(Float), 1, pFile); fread(m_aulKeys, sizeof(TEKeyState), NUM_KEYS, pFile); fread(&m_bUseJoystick, sizeof(bool), 1, pFile); fread(&m_JoystickAccel, sizeof(FRJoystickAccel), 1, pFile); fread(&m_fJoystickSensitivity, sizeof(Float), 1, pFile); fread(&m_bBonusCarAvailable, sizeof(bool), 1, pFile); fread(&m_ulCurrCamPos, sizeof(UInt32), 1, pFile); fread(&m_ulCurrTrack, sizeof(UInt32), 1, pFile); fread(&m_ulNumLaps, sizeof(UInt32), 1, pFile); fread(&m_CurrGameType, sizeof(FRGameType), 1, pFile); fread(&m_CurrCar, sizeof(FRCarName), 1, pFile); fread(&ulSize, sizeof(UInt32), 1, pFile); acName = new Char[ulSize + 1]; fread(acName, sizeof(Char), ulSize, pFile); acName[ulSize] = '\0'; m_PlayerName.Set(acName); SafeDeleteA(acName); fread(&m_IP, sizeof(m_IP), 1, pFile); fread(&m_usNetPort, sizeof(UInt16), 1, pFile); fclose(pFile); } if(m_Lang == ENGLISH) Language = "ENGLISH"; else if(m_Lang == GERMAN) Language = "GERMAN"; pTrans->SetLanguage(Language, LangFile); pFile = fopen("frcareer.dat", "rb"); if(pFile != NULL) { m_pCareer = new FRCareerInfo; fread(m_pCareer, sizeof(FRCareerInfo), 1, pFile); m_usDifficulty = m_pCareer->usDifficulty; fclose(pFile); } else m_pCareer = NULL; } void FRApp::SaveConfig(void) { FILE* pFile = fopen("frconfig.dat", "wb"); UInt32 ulSize = m_PlayerName.GetLength(); Char *pcName = m_PlayerName.Get(); if(pFile == NULL) return; fwrite(&m_usScreenWidth, sizeof(UInt16), 1, pFile); fwrite(&m_usScreenHeight, sizeof(UInt16), 1, pFile); fwrite(&m_usScreenBpp, sizeof(UInt16), 1, pFile); fwrite(&m_bPlayIntro, sizeof(bool), 1, pFile); fwrite(&m_bShowTacho, sizeof(bool), 1, pFile); fwrite(&m_bCamAnimation, sizeof(bool), 1, pFile); fwrite(&m_bUseMirror, sizeof(bool), 1, pFile); fwrite(&m_Lang, sizeof(FRLanguage), 1, pFile); fwrite(&m_Details, sizeof(FRDetailLevel), 1, pFile); fwrite(&m_Music, sizeof(FRBackgroundMusic), 1, pFile); fwrite(&m_fGeneralVolume, sizeof(Float), 1, pFile); fwrite(&m_fMusicVolume, sizeof(Float), 1, pFile); fwrite(m_aulKeys, sizeof(TEKeyState), NUM_KEYS, pFile); fwrite(&m_bUseJoystick, sizeof(bool), 1, pFile); fwrite(&m_JoystickAccel, sizeof(FRJoystickAccel), 1, pFile); fwrite(&m_fJoystickSensitivity, sizeof(Float), 1, pFile); fwrite(&m_bBonusCarAvailable, sizeof(bool), 1, pFile); fwrite(&m_ulCurrCamPos, sizeof(UInt32), 1, pFile); fwrite(&m_ulCurrTrack, sizeof(UInt32), 1, pFile); fwrite(&m_ulNumLaps, sizeof(UInt32), 1, pFile); fwrite(&m_CurrGameType, sizeof(FRGameType), 1, pFile); fwrite(&m_CurrCar, sizeof(FRCarName), 1, pFile); fwrite(&ulSize, sizeof(UInt32), 1, pFile); fwrite(pcName, sizeof(Char), ulSize, pFile); fwrite(&m_IP, sizeof(m_IP), 1, pFile); fwrite(&m_usNetPort, sizeof(UInt16), 1, pFile); fclose(pFile); } void FRApp::SaveCareer(void) { TEAssert(m_pCareer); FILE* pFile = fopen("frcareer.dat", "wb"); if(pFile == NULL) return; fwrite(m_pCareer, sizeof(FRCareerInfo), 1, pFile); fclose(pFile); } void FRApp::ApplyDetailSettings(void) { switch(m_Details){ case VERYHIGH: m_pRenderer->SetPerspective(90.0f, 4.0f/3.0f, 1.0f, 2500.0f); m_pEngine->SetShadowMethod(SHADOW_STENCIL_VOLUME); m_pEngine->SetModelDetail(LOD_FULL); m_pEngine->SetModelShadowLOD(SHADOWLOD_ONE_MINUS_CURRENT); m_pEngine->SetMaxDecalDistance(1000.0f); m_pEngine->SetMaxDecals(150); m_pEngine->SetMaxCoronaDistance(1250.0f); m_pEngine->SetMaxShadowDistance(1000.0f); m_pEngine->SetMaxDynamicLightDistance(1000.0f); m_pEngine->SetDecalUse(true); m_pEngine->SetLightMapping(true); m_pEngine->SetTextureDetail(TEXTURE_FULL); m_pEngine->SetDynamicLightUse(true); FRCar::ms_bTyreDecals = true; FRCar::ms_bSmoke = true; break; case HIGH: m_pRenderer->SetPerspective(90.0f, 4.0f/3.0f, 1.0f, 2250.0f); m_pEngine->SetShadowMethod(SHADOW_PROJECTED_STENCIL); m_pEngine->SetModelDetail(LOD_FULL); m_pEngine->SetModelShadowLOD(SHADOWLOD_ONE_MINUS_CURRENT); m_pEngine->SetMaxDecalDistance(750.0f); m_pEngine->SetMaxDecals(100); m_pEngine->SetMaxCoronaDistance(1000.0f); m_pEngine->SetMaxShadowDistance(750.0f); m_pEngine->SetMaxDynamicLightDistance(750.0f); m_pEngine->SetDecalUse(true); m_pEngine->SetLightMapping(true); m_pEngine->SetTextureDetail(TEXTURE_FULL); m_pEngine->SetDynamicLightUse(true); FRCar::ms_bTyreDecals = true; FRCar::ms_bSmoke = true; break; case MEDIUM: m_pRenderer->SetPerspective(90.0f, 4.0f/3.0f, 1.0f, 1750.0f); m_pEngine->SetShadowMethod(SHADOW_PROJECTED); m_pEngine->SetModelDetail(LOD_MEDIUM); m_pEngine->SetModelShadowLOD(SHADOWLOD_LAST); m_pEngine->SetMaxDecalDistance(600.0f); m_pEngine->SetMaxDecals(50); m_pEngine->SetMaxCoronaDistance(750.0f); m_pEngine->SetMaxShadowDistance(500.0f); m_pEngine->SetMaxDynamicLightDistance(500.0f); m_pEngine->SetDecalUse(true); m_pEngine->SetLightMapping(true); m_pEngine->SetTextureDetail(TEXTURE_FULL); m_pEngine->SetDynamicLightUse(true); FRCar::ms_bTyreDecals = true; FRCar::ms_bSmoke = false; break; case LOW: m_pRenderer->SetPerspective(90.0f, 4.0f/3.0f, 1.0f, 1500.0f); m_pEngine->SetShadowMethod(SHADOW_FAKE); m_pEngine->SetModelDetail(LOD_MEDIUM); m_pEngine->SetModelShadowLOD(SHADOWLOD_LAST); m_pEngine->SetMaxDecalDistance(512.0f); m_pEngine->SetMaxCoronaDistance(750.0f); m_pEngine->SetMaxShadowDistance(300.0f); m_pEngine->SetDecalUse(false); m_pEngine->SetLightMapping(false); m_pEngine->SetTextureDetail(TEXTURE_FULL); m_pEngine->SetDynamicLightUse(false); FRCar::ms_bTyreDecals = false; FRCar::ms_bSmoke = false; break; case VERYLOW: m_pRenderer->SetPerspective(90.0f, 4.0f/3.0f, 1.0f, 1250.0f); m_pEngine->SetShadowMethod(SHADOW_NONE); m_pEngine->SetModelDetail(LOD_LOWEST); m_pEngine->SetModelShadowLOD(SHADOWLOD_LAST); m_pEngine->SetMaxDecalDistance(512.0f); m_pEngine->SetMaxCoronaDistance(750.0f); m_pEngine->SetDecalUse(false); m_pEngine->SetLightMapping(false); m_pEngine->SetTextureDetail(TEXTURE_MEDIUM); m_pEngine->SetDynamicLightUse(false); FRCar::ms_bTyreDecals = false; FRCar::ms_bSmoke = false; break; }; m_usMirrorWidth = (UInt16) (300.0f * m_usScreenWidth / 1024.0f); m_usMirrorHeight = m_usMirrorWidth / 4; } UInt32 FRApp::GetClientPos(TEClient* pClient) { if(pClient == m_apClients[0]) return 0; else if(pClient == m_apClients[1]) return 1; else if(pClient == m_apClients[2]) return 2; return 0; } void FRApp::StartNetworkRace(void) { FRCountdown Msg; Msg.ulMsgType = FRCOUNTDOWN; Msg.ucState = 1; memset(m_apCars, 0, sizeof(FRCar*) * 4); m_pCar = m_apCars[0] = GetCar(m_CurrCar, m_aStartPositions[3], m_aStartRotations[3]); m_pCar->m_DriverName = m_PlayerName; m_pCar->m_Type = LOCAL; m_pEngine->AddObjectToWorld(m_pCar); m_aulPosition[0] = 0; m_aulPosition[1] = 1; m_aulPosition[2] = 2; m_aulPosition[3] = 3; m_GameState = SERVERRACE; m_pEngine->ShowCursor(false); m_bShowAbortMenu = false; for(UInt32 ulCount = 0; ulCount < m_ulNumClients; ulCount++) { m_apCars[1+ulCount] = GetCar(m_aClientCars[ulCount], m_aStartPositions[2-ulCount], m_aStartRotations[2-ulCount]); m_apCars[1+ulCount]->m_Type = NETWORK; m_apCars[1+ulCount]->m_DriverName = m_apClients[ulCount]->acName; m_pEngine->AddObjectToWorld(m_apCars[1+ulCount]); } TETextureManager::GetTextureManager()->ReleaseUnusedTextures(); TEModelManager::GetModelManager()->FreeUnusedModels(); TESoundManager::GetSoundManager()->FreeUnusedSounds(); m_pNetworkManager->SendDataToAllClients(&Msg, sizeof(Msg)); m_ulCountdown = m_pTimer->GetTime(); } FRCar* FRApp::GetCar(FRCarName &rCar, TEVector &rCenter, Float fInitYRot) { FRCar* pCar; switch(rCar){ case PICKUP: pCar = new FRPickup(rCenter, fInitYRot); break; case MONSTERHUMMER: pCar = new FRMonsterHummer(rCenter, fInitYRot); break; case HUMMER: pCar = new FRHummer(rCenter, fInitYRot); break; case GOLF: pCar = new FRGolf(rCenter, fInitYRot); break; case FUNERALCAR: pCar = new FRFuneralCar(rCenter, fInitYRot); break; case DODGE: pCar = new FRDodge(rCenter, fInitYRot); break; case COP: pCar = new FRCop(rCenter, fInitYRot); break; case AMBULANCE: pCar = new FRAmbulance(rCenter, fInitYRot); break; default: case ACLASS: pCar = new FRAClass(rCenter, fInitYRot); break; }; return pCar; }